#include "tools.h"
Visitor *p;//申请堆内存，存放登录信息
Visitor *v;//活跃指针
int exit_flag;//系统即将退出的标志
bool quit_flag;
//按任意按键继续..
void Anykey(void)
{
	puts("按任意按键继续...");
	//防止输入缓冲区中有残留的字符，会导致getch直接返回
	//因此清理输入缓冲区
	stdin -> _IO_read_ptr = stdin -> _IO_read_end;
	getch();
}
//初始化并申请堆内存
void Init(void)
{
	CLC;
	printf("系统启动中...\n");
	p=(Visitor *)malloc(sizeof(Visitor)*MAX_NUMBER);
	v=NULL;
	exit_flag=0;
	quit_flag=false;
	Readsigninmsg("signin.txt");
	WAIT(2);
}
//读取注册表信息
void Readsigninmsg(const char *filename)
{
	FILE *frp = fopen(filename,"r");
	if(NULL == frp)
	{
		perror("fopen");	
		Anykey();
		return;
	}
	Visitor *dest = &p[0];
	while(1)
	{
		if(fgetc(frp)==EOF)
				break;
		int temp1;
		int temp2;
		fscanf(frp," %s %c %f %f %f %d %d %d %s %c",dest->name,&dest->sex,&dest->grade[0],&dest->grade[1],&dest->grade[2],&temp1,&temp2,&dest->id,dest->password,&dest->level);
		dest->issigned=temp1;
		dest->enter_error=temp2;
		fgetc(frp);
		dest++;
	}
	fclose(frp);
	return;
}
//将注册信息写入注册表中
void Writesigninmsg(const char *filename,Visitor *dest)
{
	FILE *fap = fopen(filename,"a");
	if(NULL == fap)
	{
		perror("fopen");	
		Anykey();
		return;
	}
	fprintf(fap," %s %c %f %f %f %d %d %d %s %c\n",dest->name,dest->sex,dest->grade[0],dest->grade[1],dest->grade[2],dest->issigned,dest->enter_error,dest->id,dest->password,dest->level);
	fclose(fap);
	return;
}
void Modifysigninmsg(const char *filename,Visitor *dest,const int row)
{
	FILE *fop=fopen(filename,"r");
	if(NULL == fop)
	{
		perror("fopen");	
		Anykey();
		return;
	}
	char tmpname[]="temple.txt";
	char buf[512];
	FILE *fnp=fopen(tmpname,"w");
	if(NULL == fnp)
	{
		perror("fopen");	
		Anykey();
		return;
	}
	for(int i=1;i<=getFilesLine(filename);i++)
	{
		if(i==row)
		{
			fgets(buf,512,fop);
			fprintf(fnp," %s %c %f %f %f %d %d %d %s %c\n",dest->name,dest->sex,dest->grade[0],dest->grade[1],dest->grade[2],dest->issigned,dest->enter_error,dest->id,dest->password,dest->level);
		}
		else
		{
			fgets(buf,512,fop);
			fputs(buf,fnp);
		}
	}
	
	fclose(fop);
	fclose(fnp);
	remove(filename);
	rename(tmpname,filename);
	return;
}
int getFilesLine(const char *filename)
{
	FILE *fp=fopen(filename,"r+");
	int ch;
	int lines=0;
	if(NULL == fp)
	{
		perror("fopen");	
		Anykey();
		return 0;
	}
	while((ch = fgetc(fp))!=EOF)
	{
		if(ch=='\n') lines++;
	}
	fclose(fp);
	return lines;
}
int getCurrentIndex(const int id)
{
	int index=1;
	Visitor *curdest=Findmember(id);
	Visitor *dest=&p[0];
	while(Translate(dest->level)!=NULL)
	{
		if(dest->id!=curdest->id)
		{
		 	index++;
		 	dest++;
		}
		else
		{
			break;
		}
		
	}
	return index;
}
//退出系统并释放堆内存
void Exit()
{
	printf("程序即将退出...\n");
	free(p);	
	p=NULL;
}
//返回比输入权限低一级的权限
char Lowerlevel(const char level)
{
	switch(level)
	{
		case 's':return 's';
		case 't':return 's';
		case 'a':return 't';
		default:return 'o';
	}
}
//返回比输入权限高一级的权限
char Higherlevel(const char level){
	switch(level)
	{
		case 's':return 't';
		case 't':return 'a';
		case 'a':return 'a';
		default:return 'o';
	}		
}
//将输入的单个字符翻译并返回，可以手动添加新词汇
char* Translate(const char ch)
{
	switch(ch)
	{
		case 'm':return "男";
		case 'w':return "女";
		case 's':return "学生";
		case 't':return "老师";
		case 'a':return "校长";
		case 'q':return "离职";
		case 'd':return "退学";
		case 'o':return "游客";
		default:return NULL;
	}
}
//权限比较，返回true则说明可以使用某项功能
bool Levelcmp(const char level1,const char level2)
{
	switch(level1)
	{
		case 'a':if(level2=='a') return true; else if(level2=='t') return true; else if(level2=='q') return true; else return false; break;
		case 's':if(level2=='s')return true;return false;
		case 't':if(level2=='s') return true;else if(level2=='d') return true;else return false;break;
		default :return false; break;
	}
}
//通过id遍历结构体数组，若结构体数组中有此id，则返回true
bool Findid(const int id)
{
	Visitor *dest=&p[0];
	while(Translate(dest->level)!=NULL)
	{
		if(dest->id==id) return true;
		dest++;
	}
	return false;
}
Visitor *Findname(const char* name)
{
	Visitor *dest=&p[0];
		while(Translate(dest->level)!=NULL)
		{
			if(strcmp(dest->name,name)==0) return dest;	
			dest++;
		}
	return NULL;
}
//输入姓名返回其在结构体数组的地址
//输入id返回其对应密码
char* Findpassword(const int id)
{
	Visitor *dest=&p[0];
	if(Findid(id))
	{
		while(Translate(dest->level)!=NULL)
		{
			if(dest->id==id) return dest->password;	
			dest++;
		}
	}
	return NULL;
}
//输入id返回此id在结构体数组中的地址
Visitor* Findmember(const int id)
{
	Visitor *dest=&p[0];
	if(Findid(id))
	{
		while(Translate(dest->level)!=NULL)
		{
			if(dest->id==id) return dest;	
			dest++;
		}
	}
	return NULL;
}
int Getgroupnumber(char cmd)
{
	int num=0;
	Visitor *dest=&p[0];
	while(Translate(dest->level)!=NULL)
	{
		if(dest->level==cmd||cmd=='o') num++;
		dest++;
	}	
	return num;
}
bool Islegal(char* password)
{
	char *dest=password;
	while(*dest!='\0')
	{
		if(!((*dest>='a'&&*dest<='z')||(*dest>='0'&&*dest<='9')||(*dest=='_')))
		return false;
		dest++;
	}
	if(strlen(dest)>16) return false;
	return true;
}
bool Samename(const char *name)
{
	Visitor *dest=&p[0];
	while(Translate(dest->level)!=NULL)
	{
		if(strcmp(dest->name,name)==0&&Translate((dest+1)->level)!=NULL) return true;
		dest++;
	}
	return false;
}
void Full(Visitor *w,const char level)
{
			w->id=rand()%MAX_NUMBER;
		Visitor *dest=&p[0];
	while(Translate(dest->level)!=NULL)
	{
		if(w->id==dest->id)
		{
			w->id=rand()%MAX_NUMBER;
			dest=&p[0];
		}
		dest++;
	}//为了保证生成的学工号不重复
	w->enter_error=false;
	w->issigned=false;
	strcpy(w->password,RESET_PASSWORD);
	w->level=level;
	w->grade[0] = 0;
	w->grade[1] = 0;
	w->grade[2] = 0;
	return;
}
char* Contains(const char *str1,const char *str2)
{
	/*
	if(NULL==str1||NULL==str2) return false;
	int s=1;
	int i=0;
	int j=0;
	while(j<strlen(str1))
	{
		if(strlen(str1)-strlen(str2)<j) break;
		if((*str1)!=(*str2)) str1++;
		else
		{
			while(i<strlen(str2)-1)
			{
				i++;
				if((*(str1+i))==(*(str2+i)))
				{
				 	s++;
				}
				else
				{
					 break;
				} 	
			}
			if(s==strlen(str2))
			{
				return true;
			}
			else
			{
				str1++;
				s=1;
				i=0;
			}
		}		
		j++;
	}
	return false;
	*/
	return strstr(str1,str2);
}
void Samefind(const char* name)
{
	Visitor *dest=&p[0];
		while(Translate(dest->level)!=NULL)
		{
			if(Contains(dest->name,name)!=NULL)
			Displaystu(Findname(dest->name)->id);
			dest++;
		}
		puts("输出完毕");
		Anykey();
	return;
}
void Displayonemsg(const int id,const char level)
{
	if(!Findid(id))
	{
		printf("此学工号不存在!\n");
		Anykey();
		return;
	}
	Visitor *dest=Findmember(id);
	printf("姓名:%s\t性别:%s\t学工号:%d\t权限:%s\n",dest->name,Translate(dest->sex),dest->id,Translate(dest->level));
	if(dest->level=='s')
	printf("语文:%.1f\t数学:%.1f\t英语:%.1f\n",dest->grade[0],dest->grade[1],dest->grade[2]);
	Anykey();
	return;
}
void Displaystu(const int id)
{
	if(!Findid(id))
	{
		printf("此学工号不存在!\n");
		return;
	}
	Visitor *dest=Findmember(id);
	if(dest->level!='s')
	{
		return;
	}
	printf("姓名:%s\t性别:%s\t学工号:%d\t权限:%s\n",dest->name,Translate(dest->sex),dest->id,Translate(dest->level));
	printf("语文:%.1f\t数学:%.1f\t英语:%.1f\n",dest->grade[0],dest->grade[1],dest->grade[2]);
	return;
}
